package nl.boektrust.btsoep.server;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;

import nl.boektrust.btsoep.shared.model.PhysicalBookManifestation;

import org.restlet.data.Status;
import org.restlet.resource.Get;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;

import com.googlecode.objectify.Key;

public class RestBookByKeyResource extends ServerResource {
	PersistentServiceImpl persistentServiceImpl = new PersistentServiceImpl();


	@Get 
	public String retrieve() {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		Document doc = null;
		try {
			doc = factory.newDocumentBuilder().newDocument();
		} catch (Exception e) {
			System.err.println("Exception");
			e.printStackTrace();

			System.err.println(e.getMessage());
			System.err.println(e.getStackTrace());
			throw(new ResourceException(new Status(501), "RestBookResource failed to allocate a Document resource, critical error."));
		}

		//PrintWriter out = response.getWriter();
		//response.setContentType("text/xml");

		String idString = (String) getRequest().getAttributes().get("key");
		if (idString == null || idString.length() == 0) {
			throw(new ResourceException(new Status(400), "error: key is not specified."));
		}
		long id = new Long(idString).longValue();

		Key<PhysicalBookManifestation> key = new Key<PhysicalBookManifestation>(PhysicalBookManifestation.class, id);

		PhysicalBookManifestation theBook = persistentServiceImpl.getBookByKey(key);
		if (theBook == null) {
			throw(new ResourceException(new Status(404), "Book not found."));
		}
		DocumentFragment onixMessage = OnixUtility.getOnixMessage();
		if (onixMessage == null) {
			System.err.println("fragment is null");
			return "fragment is null";
		}
		doc.appendChild(doc.importNode(onixMessage, true));
		if (onixMessage.getOwnerDocument() == null) {
			System.err.println("owner document is null");
			return "owner document is null";
		}
		// add header
		DocumentFragment header = OnixUtility.getOnixMessageHeader();
		doc.getDocumentElement().appendChild(doc.importNode(header, true));

		// add product node for first product
		DocumentFragment product = OnixUtility.encodeToOnix(theBook);
		doc.getDocumentElement().appendChild(doc.importNode(product, true));

		// transform and output the book
		Transformer transformer;
		try {
			// see: http://comments.gmane.org/gmane.org.google.gwt/45531
			System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
			transformer = TransformerFactory.newInstance().newTransformer();
			//transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			//javax.xml.transform.Source src = new DOMSource(docFragment.getOwnerDocument());
			//if (src == null) out.println("src is null");
			java.io.StringWriter writer = new StringWriter();
			javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(writer);
			DOMSource source = new DOMSource(doc);
			//out.println("Got an XML; root node has  "+doc.getDocumentElement().getChildNodes().getLength()+" nodes");
			//out.println("First node under rootnode: "+doc.getDocumentElement().getChildNodes().item(0).getNodeName());
			transformer.transform(source, result);
			String xmlString = result.getWriter().toString();
			if (xmlString == null) System.out.println("xmlString is null");
			System.err.println("xmlString: " + xmlString);
			return(xmlString);
		} catch (Exception e) {
			System.err.println("Exception thrown: " + e.getMessage());
			System.out.print("Exception thrown: " + e.getMessage());
			e.printStackTrace();
		}
		throw(new ResourceException(new Status(501), "RestBookResource finished without any meaningful status, critical error."));

		//	return "";
	}
}
